/**
 * Copyright ©2016-2020 northkingbpo Corporation, All Rights Reserved
 * http://www.northkingbpo.net/
 */
package com.north.king.profile.http.client.resttemplate.server.data;

import com.north.king.profile.http.client.resttemplate.common.ConstantVariable;
import com.north.king.profile.http.client.resttemplate.domain.User;
import com.north.king.profile.http.client.resttemplate.domain.UserProperties;

import java.util.*;

/**
 * class info
 *
 * @author hujia
 * @date 2019-01-09 09:04
 */
public class UserDataFactory {

    // top [85,100]
    // good [65,85)
    // normal [50,65)
    // bad [0,50)
    private int[] gradeBound = {0, 50, 65, 85, 100};
    private double[] userRate = {0.05, 0.10, 0.70, 0.15};

    public User createUser(UserProperties userProperties, String userId) {
        // business kind number
        int BusiTotal = userProperties.getBusiTypeEnd() + 1 - userProperties.getBusiTypeBegin();
        // workqueue role number
        int workqueueTotal = userProperties.getWorkqueueEnd() + 1 - userProperties.getWorkqueueBegin();
        // total number
        int total = BusiTotal * workqueueTotal;
        // round
        int top = new Double(total * userRate[0]).intValue();
        // numberSet
        Set<Integer> numberSet = new HashSet<>();
        int good = new Double(total * userRate[1]).intValue();
        int bad = new Double(total * userRate[3]).intValue();
        List<Integer> topSet = createNumber(top, total, numberSet);
        List<Integer> goodSet = createNumber(good, total, numberSet);
        List<Integer> badSet = createNumber(bad, total, numberSet);
        User user = new User();
        user.setUserId(userId);
        user.init(BusiTotal, workqueueTotal, userProperties.getBusiTypeBegin(), userProperties.getWorkqueueBegin());
        joinUser(topSet, user, workqueueTotal, userProperties.getBusiTypeBegin(),
                userProperties.getWorkqueueBegin(), gradeBound[4] - gradeBound[3], gradeBound[3]);
        joinUser(goodSet, user, workqueueTotal, userProperties.getBusiTypeBegin(),
                userProperties.getWorkqueueBegin(), gradeBound[3] - gradeBound[2], gradeBound[2]);
        joinUser(badSet, user, workqueueTotal, userProperties.getBusiTypeBegin(),
                userProperties.getWorkqueueBegin(), gradeBound[1] - gradeBound[0], gradeBound[0]);
        completeKey(user, userProperties.getOrgBusinessBegin(), userProperties.getOrgBusinessEnd());
        return user;
    }

    private void completeKey(User user, int orgBusinessBegin, int orgBusinessEnd) {
        Map<String, Integer> keyMap = new HashMap<>();
        for (int i = orgBusinessBegin; i < orgBusinessEnd; ++i) {
            for (Map.Entry<String, Integer> entry : user.getDelegateList().entrySet()) {
                String grade = "";
                String key = entry.getKey() + "orgBusinessBegin" + i + getGrade(entry.getValue());
                keyMap.put(key, entry.getValue());
            }
        }
        user.setDelegateList(keyMap);
    }

    private String getGrade(Integer value) {
        if (value > gradeBound[0] && value < gradeBound[1]) {
            return "bad";
        } else if (value >= gradeBound[1] && value < gradeBound[2]) {
            return "normal";
        } else if (value >= gradeBound[2] && value < gradeBound[3]) {
            return "good";
        } else if (value >= gradeBound[3] && value < gradeBound[4]) {
            return "top";
        } else {
            return "null";
        }
    }


    private List<Integer> createNumber(int num, int total, Set<Integer> numberSet) {
        int i = 0;
        List<Integer> result = new ArrayList<>();
        Random random = new Random();
        while (result.size() < num) {
            int number = random.nextInt(total) + 1;
            if (numberSet.contains(number)) {
                continue;
            }
            result.add(number);
            numberSet.add(number);
        }
        return result;
    }

    private void joinUser(List<Integer> list, User user, int workqueueTotal,
                          int busiBase, int workqueuBase, int randomBound, int randomBase) {
        Random random = new Random();
        for (Integer tmp : list) {
            int workNumber = tmp % workqueueTotal;
            int busiNumber = (tmp - workNumber) / workqueueTotal;
            String key = ConstantVariable.CONDITION_ONE + (busiNumber + busiBase) + ConstantVariable.SEPARATOR
                    + ConstantVariable.CONDITION_TWO + (workNumber + workqueuBase);
            int value = random.nextInt(randomBound) + randomBase;
            user.getDelegateList().put(key, value);
        }
    }

    public List<User> buildList() {
        List<UserProperties> userPropertiesList = new ArrayList<>();
        userPropertiesList.add(new UserProperties(1, 40, 1,
                1, 1, 200));
        userPropertiesList.add(new UserProperties(1, 40, 2,
                2, 1, 200));
        userPropertiesList.add(new UserProperties(1, 20, 1,
                1, 1, 40));
        userPropertiesList.add(new UserProperties(1, 20, 1,
                1, 41, 80));
        userPropertiesList.add(new UserProperties(1, 20, 1,
                1, 81, 120));
        userPropertiesList.add(new UserProperties(1, 20, 1,
                1, 121, 160));
        userPropertiesList.add(new UserProperties(1, 20, 1,
                1, 161, 200));
        userPropertiesList.add(new UserProperties(1, 20, 2,
                2, 1, 40));
        userPropertiesList.add(new UserProperties(1, 20, 2,
                2, 41, 80));
        userPropertiesList.add(new UserProperties(1, 20, 2,
                2, 81, 120));
        userPropertiesList.add(new UserProperties(1, 20, 2,
                2, 121, 160));
        userPropertiesList.add(new UserProperties(1, 20, 2,
                2, 161, 200));
        userPropertiesList.add(new UserProperties(21, 40, 1,
                1, 1, 40));
        userPropertiesList.add(new UserProperties(21, 40, 1,
                1, 41, 80));
        userPropertiesList.add(new UserProperties(21, 40, 1,
                1, 81, 120));
        userPropertiesList.add(new UserProperties(21, 40, 1,
                1, 121, 160));
        userPropertiesList.add(new UserProperties(21, 40, 1,
                1, 161, 200));
        userPropertiesList.add(new UserProperties(21, 40, 2,
                2, 1, 40));
        userPropertiesList.add(new UserProperties(21, 40, 2,
                2, 41, 80));
        userPropertiesList.add(new UserProperties(21, 40, 2,
                2, 81, 120));
        userPropertiesList.add(new UserProperties(21, 40, 2,
                2, 121, 160));
        userPropertiesList.add(new UserProperties(21, 40, 2,
                2, 161, 200));
        List<User> userList = new ArrayList<>();
        for (int j = 0; j < userPropertiesList.size(); ++j) {
            for (int i = 0; i < 10; ++i) {
                userList.add(createUser(userPropertiesList.get(j), String.format("user%02d%02d", j, i)));
            }
        }
        return userList;
    }

}
